home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol07 / 02 / controls / paint.c < prev    next >
C/C++ Source or Header  |  1992-02-29  |  11KB  |  384 lines

  1. /*
  2.  * PAINT.C
  3.  *
  4.  * Contains any code related to MicroScroll visuals, primarily
  5.  * the WM_PAINT handler.
  6.  *
  7.  * Version 1.1, October 1991, Kraig Brockschmidt
  8.  */
  9.  
  10.  
  11. #include <windows.h>
  12. #include "muscrdll.h"
  13.  
  14. //Array of default colors, matching the order of MSCOLOR_* values.
  15. WORD rgColorDef[CCOLORS]={
  16.                          COLOR_BTNFACE,
  17.                          COLOR_BTNTEXT,
  18.                          COLOR_BTNSHADOW,
  19.                          -1,
  20.                          COLOR_WINDOWFRAME
  21.                          };
  22.  
  23. /*
  24.  * LMicroScrollPaint
  25.  *
  26.  * Purpose:
  27.  *  Handles all WM_PAINT messages for the control and paints
  28.  *  the control for the current state, whether it be clicked
  29.  *  or disabled.
  30.  *
  31.  *  PLEASE NOTE!
  32.  *  This painting routine makes no attempt at optimizations
  33.  *  and is intended for demonstration and education.
  34.  *
  35.  * Parameters:
  36.  *  hWnd            HWND Handle to the control.
  37.  *  pMS             PMUSCROLL control data pointer.
  38.  *
  39.  * Return Value:
  40.  *  LONG            0L.
  41.  */
  42.  
  43. LONG PASCAL LMicroScrollPaint(HWND hWnd, PMUSCROLL pMS)
  44.     {
  45.     PAINTSTRUCT ps;
  46.     LPRECT      lpRect;
  47.     RECT        rect;
  48.     HDC         hDC;
  49.     COLORREF    rgCr[CCOLORS];
  50.     HPEN        rgHPen[CCOLORS];
  51.     WORD        iColor;
  52.  
  53.     HBRUSH      hBrushArrow;
  54.     HBRUSH      hBrushFace;
  55.     HBRUSH      hBrushBlack;
  56.  
  57.     POINT       rgpt1[3];
  58.     POINT       rgpt2[3];
  59.  
  60.     WORD        xAdd1=0, yAdd1=0;
  61.     WORD        xAdd2=0, yAdd2=0;
  62.  
  63.     WORD        cx,  cy;    //Whole dimensions
  64.     WORD        cx2, cy2;   //Half dimensions
  65.     WORD        cx4, cy4;   //Quarter dimensions
  66.  
  67.  
  68.     lpRect=▭
  69.  
  70.     hDC=BeginPaint(hWnd, &ps);
  71.     GetClientRect(hWnd, lpRect);
  72.  
  73.     /*
  74.      * Get colors that we'll need.  We do not want to cache these
  75.      * items since we may our top-level parent window may have
  76.      * received a WM_WININICHANGE message at which time the control
  77.      * is repainted.  Since this control never sees that message,
  78.      * we cannot assume that colors will remain the same throughout
  79.      * the life of the control.
  80.      *
  81.      * We use the system color if pMS->rgCr[i] is -1, otherwise we
  82.      * use the color in pMS->rgCr[i].
  83.      */
  84.  
  85.     for (iColor=0; iColor < CCOLORS; iColor++)
  86.         {
  87.         if (-1L==pMS->rgCr[iColor])
  88.             {
  89.             //HACK:  Windows 3.0 has no system color for button highlight
  90.             if (-1==rgColorDef[iColor])
  91.                 rgCr[iColor]=RGB(255, 255, 255);
  92.             else
  93.                 rgCr[iColor]=GetSysColor(rgColorDef[iColor]);
  94.             }
  95.         else
  96.             rgCr[iColor]=pMS->rgCr[iColor];
  97.  
  98.         rgHPen[iColor]=CreatePen(PS_SOLID, 1, rgCr[iColor]);
  99.         }
  100.  
  101.     hBrushFace =CreateSolidBrush(rgCr[MSCOLOR_FACE]);
  102.     hBrushArrow=CreateSolidBrush(rgCr[MSCOLOR_ARROW]);
  103.     hBrushBlack=GetStockObject(BLACK_BRUSH);
  104.  
  105.     /*
  106.      * These values are extremely cheap to calculate for the amount
  107.      * we are going to use them.
  108.      */
  109.     cx =lpRect->right  - lpRect->left;
  110.     cy =lpRect->bottom - lpRect->top;
  111.     cx2=cx  >> 1;
  112.     cy2=cy  >> 1;
  113.     cx4=cx2 >> 1;
  114.     cy4=cy2 >> 1;
  115.  
  116.  
  117.     /*
  118.      * If one half is depressed, set the x/yAdd varaibles that we use
  119.      * to shift the small arrow image down and right.
  120.      */
  121.     if (!StateTest(pMS, MUSTATE_MOUSEOUT))
  122.         {
  123.         if (StateTest(pMS, MUSTATE_UPCLICK | MUSTATE_LEFTCLICK))
  124.             {
  125.             xAdd1=1;
  126.             yAdd1=1;
  127.             }
  128.  
  129.         if (StateTest(pMS, MUSTATE_DOWNCLICK | MUSTATE_RIGHTCLICK))
  130.             {
  131.             xAdd2=1;
  132.             yAdd2=1;
  133.             }
  134.         }
  135.  
  136.  
  137.     //Draw the face color and the outer frame
  138.     SelectObject(hDC, hBrushFace);
  139.     SelectObject(hDC, rgHPen[MSCOLOR_FRAME]);
  140.     Rectangle(hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
  141.  
  142.  
  143.     //Draw the arrows depending on the orientation.
  144.     if (MSS_VERTICAL & pMS->dwStyle)
  145.         {
  146.         //Draw the horizontal center line.
  147.         MoveTo(hDC, 0,  cy2);
  148.         LineTo(hDC, cx, cy2);
  149.  
  150.         /*
  151.          * We do one of three modifications for drawing the borders:
  152.          *  1) Both halves un-clicked.
  153.          *  2) Top clicked,   bottom unclicked.
  154.          *  3) Top unclicked, bottom clicked.
  155.          *
  156.          * Case 1 is xAdd1==xAdd2==0
  157.          * Case 2 is xAdd1==1, xAdd2=0
  158.          * Case 3 is xAdd1==0, xAdd2==1
  159.          *
  160.          */
  161.  
  162.         //Draw top and bottom buttons borders.
  163.         Draw3DButtonRect(hDC, rgHPen[MSCOLOR_HIGHLIGHT],
  164.                          rgHPen[MSCOLOR_SHADOW],
  165.                          0,  0,  cx-1, cy2,  xAdd1);
  166.  
  167.         Draw3DButtonRect(hDC, rgHPen[MSCOLOR_HIGHLIGHT],
  168.                          rgHPen[MSCOLOR_SHADOW],
  169.                          0, cy2, cx-1, cy-1, xAdd2);
  170.  
  171.  
  172.         //Select default line color.
  173.         SelectObject(hDC, rgHPen[MSCOLOR_ARROW]);
  174.  
  175.         //Draw the arrows depending on the enable state.
  176.         if (StateTest(pMS, MUSTATE_GRAYED))
  177.             {
  178.             /*
  179.              * Draw arrow color lines in the upper left of the
  180.              * top arrow and on the top of the bottom arrow.
  181.              * Pen was already selected as a default.
  182.              */
  183.             MoveTo(hDC, cx2,   cy4-2);      //Top arrow
  184.             LineTo(hDC, cx2-3, cy4+1);
  185.             MoveTo(hDC, cx2-3, cy2+cy4-2);  //Bottom arrow
  186.             LineTo(hDC, cx2+3, cy2+cy4-2);
  187.  
  188.             /*
  189.              * Draw highlight color lines in the bottom of the
  190.              * top arrow and on the ;pwer right of the bottom arrow.
  191.              */
  192.             SelectObject(hDC, rgHPen[MSCOLOR_HIGHLIGHT]);
  193.             MoveTo(hDC,   cx2-3, cy4+1);      //Top arrow
  194.             LineTo(hDC,   cx2+3, cy4+1);
  195.             MoveTo(hDC,   cx2+3, cy2+cy4-2);  //Bottom arrow
  196.             LineTo(hDC,   cx2,   cy2+cy4+1);
  197.             SetPixel(hDC, cx2,   cy2+cy4+1, rgCr[MSCOLOR_HIGHLIGHT]);
  198.             }
  199.         else
  200.             {
  201.             //Top arrow polygon
  202.             rgpt1[0].x=xAdd1+cx2;
  203.             rgpt1[0].y=yAdd1+cy4-2;
  204.             rgpt1[1].x=xAdd1+cx2-3;
  205.             rgpt1[1].y=yAdd1+cy4+1;
  206.             rgpt1[2].x=xAdd1+cx2+3;
  207.             rgpt1[2].y=yAdd1+cy4+1;
  208.  
  209.             //Bottom arrow polygon
  210.             rgpt2[0].x=xAdd2+cx2;
  211.             rgpt2[0].y=yAdd2+cy2+cy4+1;
  212.             rgpt2[1].x=xAdd2+cx2-3;
  213.             rgpt2[1].y=yAdd2+cy2+cy4-2;
  214.             rgpt2[2].x=xAdd2+cx2+3;
  215.             rgpt2[2].y=yAdd2+cy2+cy4-2;
  216.  
  217.             //Draw the arrows
  218.             SelectObject(hDC, hBrushArrow);
  219.             Polygon(hDC, (LPPOINT)rgpt1, 3);
  220.             Polygon(hDC, (LPPOINT)rgpt2, 3);
  221.             }
  222.         }
  223.     else
  224.         {
  225.         //Draw the vertical center line, assume the frame color is selected.
  226.         MoveTo(hDC, cx2, 0);
  227.         LineTo(hDC, cx2, cy);
  228.  
  229.         /*
  230.          * We do one of three modifications for drawing the borders:
  231.          *  1) Both halves un-clicked.
  232.          *  2) Left clicked,   right unclicked.
  233.          *  3) Left unclicked, right clicked.
  234.          *
  235.          * Case 1 is xAdd1==xAdd2==0
  236.          * Case 2 is xAdd1==1, xAdd2=0
  237.          * Case 3 is xAdd1==0, xAdd2==1
  238.          *
  239.          */
  240.  
  241.         //Draw left and right buttons borders.
  242.         Draw3DButtonRect(hDC, rgHPen[MSCOLOR_HIGHLIGHT],
  243.                          rgHPen[MSCOLOR_SHADOW],
  244.                          0,   0, cx2,  cy-1, xAdd1);
  245.  
  246.         Draw3DButtonRect(hDC, rgHPen[MSCOLOR_HIGHLIGHT],
  247.                          rgHPen[MSCOLOR_SHADOW],
  248.                          cx2, 0, cx-1, cy-1, xAdd2);
  249.  
  250.  
  251.         //Select default line color.
  252.         SelectObject(hDC, rgHPen[MSCOLOR_ARROW]);
  253.  
  254.         //Draw the arrows depending on the enable state.
  255.         if (StateTest(pMS, MUSTATE_GRAYED))
  256.             {
  257.             /*
  258.              * Draw arrow color lines in the upper left of the
  259.              * left arrow and on the left of the right arrow.
  260.              * Pen was already selected as a default.
  261.              */
  262.             MoveTo(hDC, cx4-2,     cy2);        //Left arrow
  263.             LineTo(hDC, cx4+1,     cy2-3);
  264.             MoveTo(hDC, cx2+cx4-2, cy2-3);      //Right arrow
  265.             LineTo(hDC, cx2+cx4-2, cy2+3);
  266.  
  267.             /*
  268.              * Draw highlight color lines in the bottom of the
  269.              * top arrow and on the ;pwer right of the bottom arrow.
  270.              */
  271.             SelectObject(hDC, rgHPen[MSCOLOR_HIGHLIGHT]);
  272.             MoveTo(hDC, cx4+1,     cy2-3);
  273.             LineTo(hDC, cx4+1,     cy2+3);
  274.             MoveTo(hDC, cx2+cx4+1, cy2);
  275.             LineTo(hDC, cx2+cx4-2, cy2+3);
  276.             }
  277.         else
  278.             {
  279.             //Left arrow polygon
  280.             rgpt1[0].x=xAdd1+cx4-2;
  281.             rgpt1[0].y=yAdd1+cy2;
  282.             rgpt1[1].x=xAdd1+cx4+1;
  283.             rgpt1[1].y=yAdd1+cy2+3;
  284.             rgpt1[2].x=xAdd1+cx4+1;
  285.             rgpt1[2].y=yAdd1+cy2-3;
  286.  
  287.             //Right arrow polygon
  288.             rgpt2[0].x=xAdd2+cx2+cx4+1;
  289.             rgpt2[0].y=yAdd2+cy2;
  290.             rgpt2[1].x=xAdd2+cx2+cx4-2;
  291.             rgpt2[1].y=yAdd2+cy2+3;
  292.             rgpt2[2].x=xAdd2+cx2+cx4-2;
  293.             rgpt2[2].y=yAdd2+cy2-3;
  294.  
  295.             //Draw the arrows
  296.             SelectObject(hDC, hBrushArrow);
  297.             Polygon(hDC, (LPPOINT)rgpt1, 3);
  298.             Polygon(hDC, (LPPOINT)rgpt2, 3);
  299.             }
  300.         }
  301.  
  302.     //Clean up
  303.     EndPaint(hWnd, &ps);
  304.  
  305.     DeleteObject(hBrushFace);
  306.     DeleteObject(hBrushArrow);
  307.  
  308.     for (iColor=0; iColor < CCOLORS; iColor++)
  309.         DeleteObject(rgHPen[iColor]);
  310.  
  311.     return 0L;
  312.     }
  313.  
  314.  
  315.  
  316.  
  317. /*
  318.  * Draw3DButtonRect
  319.  *
  320.  * Purpose:
  321.  *  Draws the 3D button look within a given rectangle.  This rectangle
  322.  *  is assumed to be bounded by a one pixel black border, so everything
  323.  *  is bumped in by one.
  324.  *
  325.  * Parameters:
  326.  *  hDC         DC to draw to.
  327.  *  hPenHigh    HPEN highlight color pen.
  328.  *  hPenShadow  HPEN shadow color pen.
  329.  *  x1          WORD Upper left corner x.
  330.  *  y1          WORD Upper left corner y.
  331.  *  x2          WORD Lower right corner x.
  332.  *  y2          WORD Lower right corner y.
  333.  *  fClicked    BOOL specifies if the button is down or not (TRUE==DOWN)
  334.  *
  335.  * Return Value:
  336.  *  void
  337.  *
  338.  */
  339.  
  340. void PASCAL Draw3DButtonRect(HDC hDC, HPEN hPenHigh, HPEN hPenShadow,
  341.                              WORD x1, WORD y1, WORD x2, WORD y2,
  342.                              BOOL fClicked)
  343.     {
  344.     HPEN        hPenOrg;
  345.  
  346.     //Shrink the rectangle to account for borders.
  347.     x1+=1;
  348.     x2-=1;
  349.     y1+=1;
  350.     y2-=1;
  351.  
  352.     hPenOrg=SelectObject(hDC, hPenShadow);
  353.  
  354.     if (fClicked)
  355.         {
  356.         //Shadow on left and top edge when clicked.
  357.         MoveTo(hDC, x1, y2);
  358.         LineTo(hDC, x1, y1);
  359.         LineTo(hDC, x2+1, y1);
  360.         }
  361.     else
  362.         {
  363.         //Lowest shadow line.
  364.         MoveTo(hDC, x1, y2);
  365.         LineTo(hDC, x2, y2);
  366.         LineTo(hDC, x2, y1-1);
  367.  
  368.         //Upper shadow line.
  369.         MoveTo(hDC, x1+1, y2-1);
  370.         LineTo(hDC, x2-1, y2-1);
  371.         LineTo(hDC, x2-1, y1);
  372.  
  373.         SelectObject(hDC, hPenHigh);
  374.  
  375.         //Upper highlight line.
  376.         MoveTo(hDC, x1,   y2-1);
  377.         LineTo(hDC, x1,   y1);
  378.         LineTo(hDC, x2,   y1);
  379.         }
  380.  
  381.     SelectObject(hDC, hPenOrg);
  382.     return;
  383.     }
  384.